/**
 * 微信小程序HTML内容解析器
 * 将HTML字符串转换为rich-text组件支持的nodes数组格式
 * 
 * 功能特性：
 * 1. 解析HTML标签和属性
 * 2. 处理内联样式转换
 * 3. 优化图片显示
 * 4. 支持常见HTML标签
 * 5. 移除不支持的标签和属性
 */

class HtmlParser {
  constructor() {
    // 支持的HTML标签映射
    this.supportedTags = {
      'p': 'view',
      'div': 'view', 
      'span': 'text',
      'strong': 'text',
      'b': 'text',
      'em': 'text',
      'i': 'text',
      'h1': 'view',
      'h2': 'view',
      'h3': 'view',
      'h4': 'view',
      'h5': 'view',
      'h6': 'view',
      'img': 'image',
      'a': 'text',
      'br': 'text',
      'ul': 'view',
      'ol': 'view',
      'li': 'view',
      'blockquote': 'view',
      'pre': 'view',
      'code': 'text'
    }

    // 默认样式配置
    this.defaultStyles = {
      'p': {
        'margin': '12px 0',
        'text-align': 'justify',
        'line-height': '1.6',
        'font-size': '16px'
      },
      'h1': {
        'font-size': '24px',
        'font-weight': '600',
        'margin': '20px 0 12px 0',
        'line-height': '1.4'
      },
      'h2': {
        'font-size': '22px',
        'font-weight': '600',
        'margin': '18px 0 10px 0',
        'line-height': '1.4'
      },
      'h3': {
        'font-size': '20px',
        'font-weight': '600',
        'margin': '16px 0 8px 0',
        'line-height': '1.4'
      },
      'h4': {
        'font-size': '18px',
        'font-weight': '600',
        'margin': '14px 0 6px 0',
        'line-height': '1.4'
      },
      'h5': {
        'font-size': '16px',
        'font-weight': '600',
        'margin': '12px 0 4px 0',
        'line-height': '1.4'
      },
      'h6': {
        'font-size': '14px',
        'font-weight': '600',
        'margin': '10px 0 2px 0',
        'line-height': '1.4'
      },
      'img': {
        'max-width': '100%',
        'height': 'auto',
        'display': 'block',
        'margin': '12px auto',
        'border-radius': '8px'
      },
      'strong': {
        'font-weight': '600'
      },
      'em': {
        'font-style': 'italic'
      },
      'blockquote': {
        'border-left': '4px solid #e0e0e0',
        'padding-left': '16px',
        'margin': '16px 0',
        'color': '#666',
        'font-style': 'italic'
      },
      'code': {
        'background-color': '#f5f5f5',
        'padding': '2px 4px',
        'border-radius': '4px',
        'font-family': 'monospace',
        'font-size': '14px'
      },
      'pre': {
        'background-color': '#f5f5f5',
        'padding': '12px',
        'border-radius': '8px',
        'overflow': 'auto',
        'margin': '12px 0'
      },
      'ul': {
        'margin': '12px 0',
        'padding-left': '20px'
      },
      'ol': {
        'margin': '12px 0',
        'padding-left': '20px'
      },
      'li': {
        'margin': '4px 0',
        'line-height': '1.6'
      }
    }
  }

  /**
   * 将HTML字符串转换为nodes数组
   * @param {string} htmlString - HTML字符串
   * @returns {Array} nodes数组
   */
  parse(htmlString) {
    if (!htmlString || typeof htmlString !== 'string') {
      return []
    }

    try {
      // 预处理HTML内容
      const processedHtml = this.preprocessHtml(htmlString)
      
      // 解析HTML为DOM结构
      const domNodes = this.parseHtmlToDom(processedHtml)
      
      // 转换为nodes格式
      const nodes = this.convertDomToNodes(domNodes)
      
      return nodes
    } catch (error) {
      console.error('HTML解析失败:', error)
      // 降级处理：返回纯文本
      return [{
        type: 'text',
        text: this.extractTextContent(htmlString)
      }]
    }
  }

  /**
   * 预处理HTML内容
   * @param {string} html - 原始HTML
   * @returns {string} 处理后的HTML
   */
  preprocessHtml(html) {
    let processed = html

    // 处理图片路径
    processed = processed.replace(
      /src="\/([^"]+)"/g,
      'src="https://college.guducat.cn/$1"'
    )

    // 移除script标签
    processed = processed.replace(/<script[^>]*>.*?<\/script>/gi, '')
    
    // 移除style标签
    processed = processed.replace(/<style[^>]*>.*?<\/style>/gi, '')
    
    // 处理自闭合标签
    processed = processed.replace(/<br\s*\/?>/gi, '<br/>')
    processed = processed.replace(/<hr\s*\/?>/gi, '<hr/>')
    processed = processed.replace(/<img([^>]*?)(?:\s*\/?)>/gi, '<img$1/>')

    // 清理多余的空白字符
    processed = processed.replace(/\s+/g, ' ')
    processed = processed.replace(/>\s+</g, '><')

    return processed.trim()
  }

  /**
   * 增强的HTML解析器
   * @param {string} html - HTML字符串
   * @returns {Array} DOM节点数组
   */
  parseHtmlToDom(html) {
    const nodes = []
    const stack = []
    let currentIndex = 0

    // 自闭合标签列表
    const selfClosingTags = ['br', 'hr', 'img', 'input', 'meta', 'link']

    while (currentIndex < html.length) {
      const nextTagStart = html.indexOf('<', currentIndex)

      if (nextTagStart === -1) {
        // 没有更多标签，处理剩余文本
        const text = html.substring(currentIndex).trim()
        if (text) {
          const targetArray = stack.length > 0 ? stack[stack.length - 1].children : nodes
          targetArray.push({
            type: 'text',
            content: this.decodeHtmlEntities(text)
          })
        }
        break
      }

      // 处理标签前的文本
      if (nextTagStart > currentIndex) {
        const text = html.substring(currentIndex, nextTagStart).trim()
        if (text) {
          const targetArray = stack.length > 0 ? stack[stack.length - 1].children : nodes
          targetArray.push({
            type: 'text',
            content: this.decodeHtmlEntities(text)
          })
        }
      }

      // 查找标签结束位置
      const tagEnd = html.indexOf('>', nextTagStart)
      if (tagEnd === -1) break

      const tagContent = html.substring(nextTagStart + 1, tagEnd)
      currentIndex = tagEnd + 1

      // 解析标签
      const tagInfo = this.parseTag(tagContent)
      if (!tagInfo) continue

      if (tagInfo.isClosing) {
        // 闭合标签 - 查找匹配的开始标签
        let foundMatch = false
        for (let i = stack.length - 1; i >= 0; i--) {
          if (stack[i].tagName === tagInfo.tagName) {
            // 找到匹配的开始标签，闭合所有中间的标签
            const completedNodes = stack.splice(i)
            completedNodes.forEach(node => {
              const targetArray = stack.length > 0 ? stack[stack.length - 1].children : nodes
              targetArray.push(node)
            })
            foundMatch = true
            break
          }
        }
      } else if (tagInfo.isSelfClosing || selfClosingTags.includes(tagInfo.tagName)) {
        // 自闭合标签
        const targetArray = stack.length > 0 ? stack[stack.length - 1].children : nodes
        targetArray.push({
          type: 'element',
          tagName: tagInfo.tagName,
          attributes: tagInfo.attributes,
          children: []
        })
      } else {
        // 开始标签
        const newNode = {
          type: 'element',
          tagName: tagInfo.tagName,
          attributes: tagInfo.attributes,
          children: []
        }
        stack.push(newNode)
      }
    }

    // 处理未闭合的标签
    while (stack.length > 0) {
      const node = stack.pop()
      const targetArray = stack.length > 0 ? stack[stack.length - 1].children : nodes
      targetArray.push(node)
    }

    return nodes
  }

  /**
   * 解码HTML实体
   * @param {string} text - 包含HTML实体的文本
   * @returns {string} 解码后的文本
   */
  decodeHtmlEntities(text) {
    const entityMap = {
      '&nbsp;': ' ',
      '&lt;': '<',
      '&gt;': '>',
      '&amp;': '&',
      '&quot;': '"',
      '&#39;': "'",
      '&apos;': "'",
      '&copy;': '©',
      '&reg;': '®',
      '&trade;': '™'
    }

    return text.replace(/&[a-zA-Z0-9#]+;/g, (entity) => {
      return entityMap[entity] || entity
    })
  }

  /**
   * 增强的标签解析器
   * @param {string} tagContent - 标签内容
   * @returns {Object|null} 标签信息
   */
  parseTag(tagContent) {
    if (!tagContent) return null

    const isClosing = tagContent.startsWith('/')
    const isSelfClosing = tagContent.endsWith('/')

    let content = tagContent
    if (isClosing) content = content.substring(1)
    if (isSelfClosing) content = content.substring(0, content.length - 1)

    // 提取标签名
    const tagNameMatch = content.match(/^(\w+)/)
    if (!tagNameMatch) return null

    const tagName = tagNameMatch[1].toLowerCase()

    if (!this.supportedTags[tagName]) {
      return null
    }

    const attributes = {}

    if (!isClosing) {
      // 更强大的属性解析
      const attrString = content.substring(tagName.length).trim()

      // 支持多种属性格式：name="value", name='value', name=value
      const attrRegex = /(\w+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+)))?/g
      let match

      while ((match = attrRegex.exec(attrString)) !== null) {
        const [, name, doubleQuoted, singleQuoted, unquoted] = match
        const value = doubleQuoted || singleQuoted || unquoted || ''
        attributes[name.toLowerCase()] = this.decodeHtmlEntities(value)
      }
    }

    return {
      tagName,
      attributes,
      isClosing,
      isSelfClosing
    }
  }

  /**
   * 将DOM节点转换为小程序nodes格式
   * @param {Array} domNodes - DOM节点数组
   * @returns {Array} nodes数组
   */
  convertDomToNodes(domNodes) {
    return domNodes.map(node => this.convertSingleNode(node)).filter(Boolean)
  }

  /**
   * 转换单个节点（增强版）
   * @param {Object} node - DOM节点
   * @returns {Object|null} 小程序node
   */
  convertSingleNode(node) {
    if (node.type === 'text') {
      const text = node.content.trim()
      return text ? {
        type: 'text',
        text: text
      } : null
    }

    if (node.type === 'element') {
      const tagName = node.tagName
      const mappedTag = this.supportedTags[tagName]

      if (!mappedTag) return null

      // 处理特殊标签
      if (tagName === 'br') {
        return {
          type: 'text',
          text: '\n'
        }
      }

      if (tagName === 'img') {
        const imgAttrs = {
          src: node.attributes.src || '',
          style: this.buildStyleString(this.defaultStyles.img, node.attributes.style),
          mode: 'widthFix' // 小程序图片模式
        }

        // 添加alt属性作为title（如果存在）
        if (node.attributes.alt) {
          imgAttrs.title = node.attributes.alt
        }

        return {
          type: 'node',
          name: 'img',
          attrs: imgAttrs
        }
      }

      // 处理链接标签
      if (tagName === 'a') {
        const linkStyle = this.buildStyleString({
          'color': '#1989fa',
          'text-decoration': 'underline'
        }, node.attributes.style)

        const nodeData = {
          type: 'node',
          name: 'text',
          attrs: {
            style: linkStyle
          }
        }

        // 处理子节点
        if (node.children && node.children.length > 0) {
          nodeData.children = this.convertDomToNodes(node.children)
        }

        return nodeData
      }

      // 处理强调标签
      if (tagName === 'strong' || tagName === 'b') {
        const strongStyle = this.buildStyleString(this.defaultStyles.strong, node.attributes.style)

        const nodeData = {
          type: 'node',
          name: 'text',
          attrs: {
            style: strongStyle
          }
        }

        if (node.children && node.children.length > 0) {
          nodeData.children = this.convertDomToNodes(node.children)
        }

        return nodeData
      }

      // 处理斜体标签
      if (tagName === 'em' || tagName === 'i') {
        const emStyle = this.buildStyleString(this.defaultStyles.em, node.attributes.style)

        const nodeData = {
          type: 'node',
          name: 'text',
          attrs: {
            style: emStyle
          }
        }

        if (node.children && node.children.length > 0) {
          nodeData.children = this.convertDomToNodes(node.children)
        }

        return nodeData
      }

      // 构建普通节点
      const nodeData = {
        type: 'node',
        name: mappedTag,
        attrs: {
          style: this.buildStyleString(this.defaultStyles[tagName] || {}, node.attributes.style)
        }
      }

      // 处理子节点
      if (node.children && node.children.length > 0) {
        const children = this.convertDomToNodes(node.children)
        if (children.length > 0) {
          nodeData.children = children
        }
      }

      return nodeData
    }

    return null
  }

  /**
   * 构建样式字符串
   * @param {Object} defaultStyle - 默认样式
   * @param {string} inlineStyle - 内联样式
   * @returns {string} 样式字符串
   */
  buildStyleString(defaultStyle = {}, inlineStyle = '') {
    const styles = { ...defaultStyle }
    
    // 解析内联样式
    if (inlineStyle) {
      const inlineRules = inlineStyle.split(';')
      inlineRules.forEach(rule => {
        const [property, value] = rule.split(':').map(s => s.trim())
        if (property && value) {
          styles[property] = value
        }
      })
    }

    // 转换为样式字符串
    return Object.entries(styles)
      .map(([key, value]) => `${key}: ${value}`)
      .join('; ')
  }

  /**
   * 提取纯文本内容（降级处理）
   * @param {string} html - HTML字符串
   * @returns {string} 纯文本
   */
  extractTextContent(html) {
    return html
      .replace(/<[^>]*>/g, '')
      .replace(/&nbsp;/g, ' ')
      .replace(/&lt;/g, '<')
      .replace(/&gt;/g, '>')
      .replace(/&amp;/g, '&')
      .replace(/\s+/g, ' ')
      .trim()
  }
}

// 创建全局实例
const htmlParser = new HtmlParser()

/**
 * 简化版HTML解析器 - 临时解决方案
 * @param {string} htmlString - HTML字符串
 * @returns {Array} rich-text nodes数组
 */
function parseHtmlToNodesSimple(htmlString) {
  if (!htmlString || typeof htmlString !== 'string') {
    return []
  }

  try {
    console.log('使用简化版解析器处理HTML')

    // 预处理HTML
    let processed = htmlString

    // 处理图片路径
    processed = processed.replace(
      /src="\/([^"]+)"/g,
      'src="https://college.guducat.cn/$1"'
    )

    // 移除script和style标签
    processed = processed.replace(/<script[^>]*>.*?<\/script>/gi, '')
    processed = processed.replace(/<style[^>]*>.*?<\/style>/gi, '')

    // 简单的标签替换处理
    const nodes = []

    // 分割HTML为段落
    const paragraphs = processed.split(/<\/p>|<br\s*\/?>/i)

    paragraphs.forEach(paragraph => {
      if (!paragraph.trim()) return

      // 清理段落内容
      let content = paragraph
        .replace(/<p[^>]*>/gi, '')
        .replace(/<\/?\w+[^>]*>/g, '') // 移除所有HTML标签
        .replace(/&nbsp;/g, ' ')
        .replace(/&lt;/g, '<')
        .replace(/&gt;/g, '>')
        .replace(/&amp;/g, '&')
        .trim()

      if (content) {
        nodes.push({
          type: 'node',
          name: 'view',
          attrs: {
            style: 'margin: 12px 0; line-height: 1.6; font-size: 16px;'
          },
          children: [{
            type: 'text',
            text: content
          }]
        })
      }
    })

    console.log('简化版解析器结果:', nodes.length, '个节点')
    return nodes.length > 0 ? nodes : [{
      type: 'text',
      text: htmlString.replace(/<[^>]*>/g, '').trim()
    }]

  } catch (error) {
    console.error('简化版解析器失败:', error)
    return [{
      type: 'text',
      text: htmlString.replace(/<[^>]*>/g, '').trim()
    }]
  }
}

/**
 * 导出的主要转换函数
 * @param {string} htmlString - HTML字符串
 * @returns {Array} rich-text nodes数组
 */
function parseHtmlToNodes(htmlString) {
  // 暂时使用简化版解析器
  return parseHtmlToNodesSimple(htmlString)

  // 原版解析器备用
  // return htmlParser.parse(htmlString)
}

module.exports = {
  HtmlParser,
  parseHtmlToNodes
}
